from fastapi import FastAPI, Depends, HTTPException, status
from fastapi.security import OAuth2PasswordBearer
from fastapi.middleware.cors import CORSMiddleware
from fastapi.encoders import jsonable_encoder
from fastapi.responses import JSONResponse
from fastapi_cache import FastAPICache
from fastapi_cache.backends.redis import RedisBackend
from fastapi_cache.decorator import cache
from redis import asyncio as aioredis
from typing import Optional
from datetime import timedelta
import jwt
from pydantic import BaseModel
import logging
from .config import AppConfig
from .arxiv_client import ArxivClient
from .trend_analyzer import TrendAnalyzer

app = FastAPI(
    title="Tech Trend Analyzer API",
    description="API for analyzing technology trends from arXiv papers",
    version="0.1.0"
)

# CORS配置
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

# 认证配置
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")

# 请求模型
class TrendRequest(BaseModel):
    query: str
    max_results: int = 50
    time_window: str = "month"

class AnalysisRequest(BaseModel):
    paper_ids: list[str]
    analysis_type: str

# 响应模型
class TrendResponse(BaseModel):
    status: str
    data: dict
    metadata: dict

class ErrorResponse(BaseModel):
    detail: str

# 依赖项
config = AppConfig()
arxiv_client = ArxivClient(config)
trend_analyzer = TrendAnalyzer(config)

@app.on_event("startup")
async def startup():
    # 初始化Redis缓存
    redis = aioredis.from_url(
        f"redis://{config.redis_host}:{config.redis_port}",
        encoding="utf8",
        decode_responses=True
    )
    FastAPICache.init(RedisBackend(redis), prefix="tech-trend-cache")

# 认证依赖
async def get_current_user(token: str = Depends(oauth2_scheme)):
    try:
        payload = jwt.decode(token, config.jwt_secret, algorithms=["HS256"])
        return payload.get("sub")
    except jwt.PyJWTError:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Invalid authentication credentials",
            headers={"WWW-Authenticate": "Bearer"},
        )

# API端点
@app.post("/api/v1/trends", response_model=TrendResponse)
@cache(expire=3600)  # 缓存1小时
async def analyze_trends(
    request: TrendRequest,
    user: str = Depends(get_current_user)
):
    """分析特定技术领域的趋势"""
    try:
        papers = await arxiv_client.search_papers(
            request.query, 
            request.max_results
        )
        trends = await trend_analyzer.analyze_trends(papers)
        
        return JSONResponse(
            status_code=status.HTTP_200_OK,
            content={
                "status": "success",
                "data": trends,
                "metadata": {
                    "query": request.query,
                    "processed_at": datetime.utcnow().isoformat()
                }
            }
        )
    except Exception as e:
        logging.error(f"Trend analysis failed: {str(e)}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="Failed to analyze trends"
        )

@app.post("/api/v1/analyze", response_model=TrendResponse)
async def analyze_papers(
    request: AnalysisRequest,
    user: str = Depends(get_current_user)
):
    """对特定论文集合进行分析"""
    try:
        # 实现具体的分析逻辑
        pass
    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail=str(e)
        )

# 健康检查
@app.get("/health")
async def health_check():
    return {"status": "healthy"}

# 错误处理
@app.exception_handler(HTTPException)
async def http_exception_handler(request, exc):
    return JSONResponse(
        status_code=exc.status_code,
        content=jsonable_encoder({"detail": exc.detail}),
    )